package com.travelDevelop.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

import com.travelDevelop.commons.bean.User;
import com.travelDevelop.commons.util.WebConst;
import com.travelDevelop.service.ChatInfoService;


@Service
public class WebSocketChat implements WebSocketHandler {
	
	@Autowired
	public ChatInfoService chatInfoService;
	
	private static final Logger logger = LogManager.getLogger(WebSocketChat.class);

    private static Map<String,StringBuffer> sessionMessage = new ConcurrentHashMap<String, StringBuffer>();
    private static Map<String,List<WebSocketSession>> courseChatSession = new ConcurrentHashMap<String,List<WebSocketSession>>();
	
    public final static String COURSE_ID = "COURSE_ID";
    
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
		 String courseId = (String) session.getAttributes().get(COURSE_ID);
		 courseChatSession.get(courseId).remove(session);
		 session.close();
	}

	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		User user = (User) session.getAttributes().get(WebConst.SESSION_LOGIN_USER);
		String courseId = (String) session.getAttributes().get(COURSE_ID);
		String userDisplayName = (String) session.getAttributes().get(WebConst.SESSION_LOGIN_USER_DISPLAY_NAME);
		if(user!=null){
			if(courseChatSession.get(courseId)==null){
				courseChatSession.put(courseId,new ArrayList<WebSocketSession>());
			}
			courseChatSession.get(courseId).add(session);
			if(userDisplayName==null){
				userDisplayName = user.getUsername();
			}
			long time = System.currentTimeMillis();
			String saveMsg = "system_welcome: 欢迎  "+userDisplayName+"  加入";
			chatInfoService.insertChatInfo(user.getId(), user.getUsername(), userDisplayName, saveMsg, time,courseId);
			broadcast(new TextMessage(saveMsg),courseId);
		}else{
			session.sendMessage(new TextMessage("system_error:请先登录！"));
			session.close();
		}
	}

	@Override
	public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
		User user = (User) session.getAttributes().get(WebConst.SESSION_LOGIN_USER);
		String userDisplayName = (String) session.getAttributes().get(WebConst.SESSION_LOGIN_USER_DISPLAY_NAME);
		String courseId = (String) session.getAttributes().get(COURSE_ID);
		if(user==null){
			session.sendMessage(new TextMessage("system_error:请先登录！"));
			session.close();
			return;
		}
		if(userDisplayName==null){
			userDisplayName = user.getUsername();
		}
		String msg = message.getPayload().toString();
		if(msg.startsWith("SYS_MSG_START:")&&msg.endsWith(":SYS_MSG_END")){
			msg = msg.substring("SYS_MSG_START:".length(), msg.length()-":SYS_MSG_END".length());
			long time = System.currentTimeMillis();
			String sendMsg = "user_info:"+userDisplayName+","+user.getUsername()+"||_|_||"+time+"||_|_||"+msg;
			chatInfoService.insertChatInfo(user.getId(), user.getUsername(), userDisplayName, msg, time,courseId);
			broadcast(new TextMessage(sendMsg),courseId);
			return;
		}
		if(msg.startsWith("SYS_MSG_START:")){
			sessionMessage.put(session.getId(), new StringBuffer(msg.substring("SYS_MSG_START:".length())));
			return;
		}else if(!msg.endsWith(":SYS_MSG_END")){
			sessionMessage.get(session.getId()).append(msg);
			return;
		}else if(msg.endsWith(":SYS_MSG_END")){
			sessionMessage.get(session.getId()).append(msg.substring(0,msg.length()-":SYS_MSG_END".length()));
			long time = System.currentTimeMillis();
			String sendMsg = "user_info:"+userDisplayName+","+user.getUsername()+"||_|_||"+System.currentTimeMillis()+"||_|_||"+sessionMessage.get(session.getId()).toString();
			String saveMsg = sessionMessage.get(session.getId()).toString();
			chatInfoService.insertChatInfo(user.getId(), user.getUsername(), userDisplayName, saveMsg, time,courseId);
			broadcast(new TextMessage(sendMsg),courseId);
		}
		if(sessionMessage.get(session.getId()).length()>1500000){
			session.sendMessage(new TextMessage("system_error:传输内容太长！"));
			sessionMessage.remove(session.getId());
			return;
		}
	}

	@Override
	public void handleTransportError(WebSocketSession session, Throwable error) throws Exception {
		// TODO Auto-generated method stub
	}

	@Override
	public boolean supportsPartialMessages() {
		return false;
	}
	
	/**
     * 群发消息
     */
    public void broadcast(final TextMessage message,String courseId) throws IOException {
    	List<WebSocketSession> list = courseChatSession.get(courseId); 
    	//线程安全问题？
        for (WebSocketSession session : list) {
            if (session!=null && session.isOpen()) {
            	//线程池怎么样？
                new Thread(() -> {
                    try {
                        if (session.isOpen()) {
                        	session.sendMessage(message);
                        }else{
                        	list.remove(session);
                        	sessionMessage.remove(session.getId());
                        }
                    } catch (Exception e) {
                        logger.error(e.getMessage(),e);
                    }
                }).start();
            }else{
            	sessionMessage.remove(session);
            	sessionMessage.remove(session.getId());
            }
        }
    }

}
